Рынок заведений общественного питания Москвы

Шаг 1. Загрузка данных и подготовка их к анализу  

In [1]:
!pip install plotly
/bin/sh: pip: command not found
In [2]:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
from plotly import graph_objects as go
import requests
import re
from bs4 import BeautifulSoup
In [3]:
data = pd.read_csv('projects/datasets/rest_data.csv')
In [4]:
data.sample(10)
Out[4]:
id object_name chain object_type address number
11145 181762 Суши Стор нет кафе город Москва, Изумрудная улица, дом 18 8
7793 23254 САТУРН-ШБС-3 СТОЛОВАЯ ШКОЛЫ 1455 нет столовая город Москва, Боровское шоссе, дом 18, корпус 4 200
13157 199531 ПлоFFхана нет предприятие быстрого обслуживания город Москва, Боровское шоссе, дом 51 12
7519 152146 Wokker да предприятие быстрого обслуживания город Москва, Ореховый бульвар, дом 14, корпус 3 0
14208 216651 Пекарня нет кафетерий город Москва, Сокольническая площадь, дом 9А 0
9039 162018 РЭДИМЭЙД нет кафе город Москва, Мичуринский проспект, дом 3 35
13366 200498 Сити Пицца да кафе город Москва, Енисейская улица, дом 5 12
13960 212759 Absolem нет кафе город Москва, улица Маросейка, дом 4/2, строен... 10
1951 22168 I Van Gogh нет ресторан город Москва, улица Большая Лубянка, дом 13/16... 90
4867 72000 Столовая ТЦ «Энтузиаст» нет кафе город Москва, Дубнинская улица, дом 79, корпус 2 40
In [5]:
data.head(10)
Out[5]:
id object_name chain object_type address number
0 151635 СМЕТАНА нет кафе город Москва, улица Егора Абакумова, дом 9 48
1 77874 Родник нет кафе город Москва, улица Талалихина, дом 2/1, корпус 1 35
2 24309 Кафе «Академия» нет кафе город Москва, Абельмановская улица, дом 6 95
3 21894 ПИЦЦЕТОРИЯ да кафе город Москва, Абрамцевская улица, дом 1 40
4 119365 Кафе «Вишневая метель» нет кафе город Москва, Абрамцевская улица, дом 9, корпус 1 50
5 27429 СТОЛ. ПРИ ГОУ СОШ № 1051 нет столовая город Москва, Абрамцевская улица, дом 15, корп... 240
6 148815 Брусника да кафе город Москва, переулок Сивцев Вражек, дом 6/2 10
7 20957 Буфет МТУСИ нет столовая город Москва, Авиамоторная улица, дом 8, строе... 90
8 20958 КПФ СЕМЬЯ-1 нет столовая город Москва, Авиамоторная улица, дом 8, строе... 150
9 28858 Столовая МТУСИ нет столовая город Москва, Авиамоторная улица, дом 8, строе... 120
  • id — идентификатор объекта;
  • object_name — название объекта общественного питания;
  • chain — сетевой ресторан;
  • object_type — тип объекта общественного питания;
  • address — адрес;
  • number — количество посадочных мест.
In [6]:
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 15366 entries, 0 to 15365
Data columns (total 6 columns):
 #   Column       Non-Null Count  Dtype 
---  ------       --------------  ----- 
 0   id           15366 non-null  int64 
 1   object_name  15366 non-null  object
 2   chain        15366 non-null  object
 3   object_type  15366 non-null  object
 4   address      15366 non-null  object
 5   number       15366 non-null  int64 
dtypes: int64(2), object(4)
memory usage: 720.4+ KB
In [7]:
data.duplicated().sum()
Out[7]:
0
In [8]:
data['object_name'] = data['object_name'].str.lower()
In [9]:
data.drop_duplicates(subset=['object_name', 'address'])
Out[9]:
id object_name chain object_type address number
0 151635 сметана нет кафе город Москва, улица Егора Абакумова, дом 9 48
1 77874 родник нет кафе город Москва, улица Талалихина, дом 2/1, корпус 1 35
2 24309 кафе «академия» нет кафе город Москва, Абельмановская улица, дом 6 95
3 21894 пиццетория да кафе город Москва, Абрамцевская улица, дом 1 40
4 119365 кафе «вишневая метель» нет кафе город Москва, Абрамцевская улица, дом 9, корпус 1 50
... ... ... ... ... ... ...
15359 222077 кофейня «шоколадница» да кафе город Москва, Кантемировская улица, дом 47 72
15360 219759 шоколадница да кафе город Москва, улица Вавилова, дом 3 36
15361 208537 шоколадница да кафе город Москва, 3-й Крутицкий переулок, дом 18 50
15362 209264 шоколадница да кафе город Москва, улица Земляной Вал, дом 33 10
15364 221900 шоколадница да кафе город Москва, поселение Московский, Киевское ш... 36

15141 rows × 6 columns

In [10]:
data['object_type'].unique()
Out[10]:
array(['кафе', 'столовая', 'закусочная',
       'предприятие быстрого обслуживания', 'ресторан', 'кафетерий',
       'буфет', 'бар', 'магазин (отдел кулинарии)'], dtype=object)
In [11]:
data['chain'].unique()
Out[11]:
array(['нет', 'да'], dtype=object)
In [12]:
data.sample(10)
Out[12]:
id object_name chain object_type address number
2530 24879 монретин нет кафе город Москва, улица Гарибальди, дом 23/54 80
14938 222595 матча нет бар город Москва, Ходынский бульвар, дом 4 0
11842 172900 лавка № 1 гастрономическая пивная нет бар город Москва, Боровское шоссе, дом 2А, корпус 3 22
11864 69506 суши wok да предприятие быстрого обслуживания город Москва, 2-я Владимирская улица, дом 42 5
14927 222963 cream station нет кафе город Москва, Ходынский бульвар, дом 4 0
7325 69596 кафе «царица» нет кафе город Москва, Ключевая улица, дом 22, корпус 2 90
7135 79567 кафе зона отдыха нет кафе город Москва, Большая Академическая улица, вла... 40
14642 221518 kurnik русские традиции сегодня нет предприятие быстрого обслуживания город Москва, Болотниковская улица, дом 12 12
14907 215313 gagawa нет кафе город Москва, Ходынский бульвар, дом 4 0
11173 182920 фермерская шаурма нет магазин (отдел кулинарии) город Москва, Открытое шоссе, дом 9, строение 14А 4

Вывод:

Изучили данные и проверили их на дубликаты.

Шаг 2. Анализ данных

Изучим соотношение видов объектов общественного питания по количеству   

In [13]:
object_type_count = data['object_type'].value_counts().reset_index()
object_type_count.columns = ['object_type','objects_number']
In [14]:
object_type_count
Out[14]:
object_type objects_number
0 кафе 6099
1 столовая 2587
2 ресторан 2285
3 предприятие быстрого обслуживания 1923
4 бар 856
5 буфет 585
6 кафетерий 398
7 закусочная 360
8 магазин (отдел кулинарии) 273
In [15]:
fig = go.Figure()
pull = [0]*len(object_type_count['objects_number'])
pull[object_type_count['objects_number'].tolist().index(object_type_count['objects_number'].max())] = 0.1
fig.add_trace(go.Pie(labels=object_type_count['object_type'], values=object_type_count['objects_number'], pull=pull))
fig.update_layout(
    title='График соотношения видов объектов общественного питания по количеству',
    title_x = 0.5,
    margin=dict(l=50, r=50, t=130, b=50))
fig.show() 

Вывод:

40% объектов общественного питания — кафе. Почти такое же количество совокупно столовых, ресторанов и предприятий быстрого обслуживания.

Построим график соотношения сетевых и несетевых заведений по количеству   

In [16]:
data['chain'].value_counts()
Out[16]:
нет    12398
да      2968
Name: chain, dtype: int64
In [17]:
plt.figure(figsize=(16,8))
plt.xlabel('Принадлежность к сети')
plt.ylabel('Количество объектов')
plt.title('График соотношения сетевых и не сетевых заведений по количеству')
data['chain'].value_counts().plot(kind='bar', color = '#5352ed')
plt.show();
In [18]:
plt.figure(figsize=(16,8))
sns.stripplot(x='chain', y='number', data=data) 
plt.xlabel('Вид объекта общественного питания')
plt.ylabel('Количество объектов')
plt.title('График соотношения сетевых и не сетевых заведений по количеству мест')
plt.show();

Вывод:

80% заведений — это не сетевые объекты, количество посадочных мест у них значительно больше, чем в сетевых заведениях.

Сетевые заведения   

In [19]:
chain_rest = data.query('chain == "да"')
In [20]:
chain_rest_count = chain_rest['object_type'].value_counts().reset_index()
chain_rest_count.columns = ['object_type','chain_objects_number']
In [21]:
chain_rest_count = chain_rest_count.merge(object_type_count)
In [22]:
chain_rest_count['part_of_chain'] = chain_rest_count['chain_objects_number']/chain_rest_count['objects_number']*100
In [23]:
chain_rest_count
Out[23]:
object_type chain_objects_number objects_number part_of_chain
0 кафе 1396 6099 22.888998
1 предприятие быстрого обслуживания 791 1923 41.133645
2 ресторан 544 2285 23.807440
3 магазин (отдел кулинарии) 78 273 28.571429
4 закусочная 56 360 15.555556
5 кафетерий 52 398 13.065327
6 бар 37 856 4.322430
7 буфет 11 585 1.880342
8 столовая 3 2587 0.115964
In [24]:
fig, ax = plt.subplots()

plt.title('График соотношения сетевых видов объектов общественного питания по количеству')
plt.xlabel('Вид заведения')
plt.ylabel('Количество заведений')

ax.bar(chain_rest_count['object_type'], chain_rest_count['objects_number'], color='#5352ed')
ax.bar(chain_rest_count['object_type'], chain_rest_count['chain_objects_number'], color='#ffa500')

fig.set_figwidth(16)    
fig.set_figheight(8)    

plt.xticks(rotation=45)

plt.show()

Вывод:

Чаще всего сетевыми становятся предприятия быстрого обслуживания(фастфуд?) — 41% сетевых заведений. 28.5% магазинов (отделов кулинарии), 23.8% ресторанов и 22.9% кафе относятся к сетевым.

In [25]:
chain_rest
Out[25]:
id object_name chain object_type address number
3 21894 пиццетория да кафе город Москва, Абрамцевская улица, дом 1 40
6 148815 брусника да кафе город Москва, переулок Сивцев Вражек, дом 6/2 10
13 22579 алло пицца да кафе город Москва, улица Авиаторов, дом 14 32
16 144107 суши wok да предприятие быстрого обслуживания город Москва, Азовская улица, дом 3 7
18 58565 тануки да ресторан город Москва, Большая Академическая улица, дом 65 160
... ... ... ... ... ... ...
15361 208537 шоколадница да кафе город Москва, 3-й Крутицкий переулок, дом 18 50
15362 209264 шоколадница да кафе город Москва, улица Земляной Вал, дом 33 10
15363 209186 шоколадница да кафе город Москва, улица Земляной Вал, дом 33 20
15364 221900 шоколадница да кафе город Москва, поселение Московский, Киевское ш... 36
15365 222535 шоколадница да кафе город Москва, Ходынский бульвар, дом 4 10

2968 rows × 6 columns

In [26]:
chain_rest_group = chain_rest.groupby('object_name', as_index=False).agg({'id':'count', 'number':'mean'})
In [27]:
chain_rest_group
Out[27]:
object_name id number
0 beverly hills diner 1 88.000000
1 bierloga 1 75.000000
2 black & white 1 40.000000
3 bocconcino 3 66.666667
4 boobo 1 46.000000
... ... ... ...
572 ямми микс 1 2.000000
573 ян примус 1 300.000000
574 японский ресторан «ваби-саби» 1 155.000000
575 япоша 2 105.000000
576 ёрш 4 112.250000

577 rows × 3 columns

In [28]:
plt.title('Количество посадочных мест в сетевых заведениях')
plt.xlabel('Количество посадочных мест')
plt.ylabel('Количество сетевых заведений')
chain_rest['number'].hist(figsize=(16,8), color = '#5352ed')
plt.show();
In [29]:
sns.set()
plt.figure(figsize=(16, 8))
sns.boxplot(x=chain_rest['number'], color='#5352ed')
plt.title('Среднее количество посадочных мест в сетевых заведениях')
plt.xlabel('Количество посадочных мест');
In [30]:
sns.set()
g = sns.jointplot(x='number', y='id', data=chain_rest_group, color='#5352ed', height=8) 
plt.suptitle('Среднее количество посадочных мест в сетевых заведениях', y=1.05)
g.set_axis_labels('Количество заведений в сети', 'Среднее количество посадочных мест');

Вывод:

Сетевых заведений с большим числом посадочных мест достаточно мало, в основной массе заведений посадочных мест до 100. Заведений в сети может быть достаточно много, но количество посадочных мест небольшое. Встречаются редкие заведения, где ресторанов в сети мало, зато в каждом очень много мест.

Проверим, какое среднее количество посадочных мест в разных типах заведений.   

In [31]:
grp_order = data.groupby('object_type').agg({'number':'mean'}).sort_values(by='number').index
In [32]:
sns.set()
plt.figure(figsize=(16, 8))
plt.title('Среднее количество посадочных мест для разных видов объектов общественного питания')
sns.barplot(x='object_type', y='number', data=data, order=grp_order)
plt.xticks(rotation=45)
plt.xlabel('Вид объекта общественного питания')
plt.ylabel('Среднее количество посадочных мест')
plt.show();
In [33]:
plt.figure(figsize=(16, 8))
plt.title('Среднее количество посадочных мест для разных видов объектов общественного питания')
sns.boxplot(x='number', y='object_type', data=data)
plt.xlabel('Количество посадочных мест')
plt.ylabel('Вид объекта общественного питания')
plt.show();

Вывод:

Больше всего посадочных мест бывает в столовых (достаточно часто они находятся при предприятиях и заводах, где численность работников значительная). Также можно встретить рестораны с большим числом посадочных мест, например, в некоторых заведениях есть банкетные залы и они специализируются на проведении массовых мероприятий (корпоративы, свадьбы и т.д).

Выделим в отдельный столбец информацию об улице из столбца address   

In [34]:
streets_names = ['улица', 'переулок', 'ул', 'проспект', 'шоссе', 'проезд', 'тупик', 'линия', 'просек',
                 'бульвар', 'проезд', 'набережная', 'площадь', 'вал', 'аллея', 'поселок', 'деревня', 'километр', 'село']
In [35]:
data['address'] = data['address'].str.replace('ё','е') 
In [36]:
def get_street(address):
    for i in [1,0,2]:
        for address_part in address.split(',')[i].split(' '):           
            if address_part in streets_names:
                street = address.split(', ')[i]
                return street
In [37]:
data['street'] = data['address'].apply(get_street)
In [38]:
data.sample(20)
Out[38]:
id object_name chain object_type address number street
6138 24849 кофе тун суши тун нет кафе город Москва, улица Вавилова, дом 24, корпус 1 43 улица Вавилова
12866 198019 чайхона восток нет кафе город Москва, улица Верхние Поля, дом 53, корп... 45 улица Верхние Поля
5457 68946 кофе хаус да кафе город Москва, Снежная улица, дом 26 71 Снежная улица
13198 192853 кислород нет кафе город Москва, Бауманская улица, дом 58, строен... 40 Бауманская улица
12976 199100 пекарня буханка нет кафетерий город Москва, Озерная улица, дом 2, корпус 3 10 Озерная улица
14431 212872 столовая «правда» нет столовая город Москва, улица Правды, дом 24, строение 4 80 улица Правды
10363 176857 шаурма нет предприятие быстрого обслуживания город Москва, Люблинская улица, дом 147 0 Люблинская улица
2678 27450 столовая при шк. 967 нет столовая город Москва, улица Молодцова, дом 4, корпус 1 240 улица Молодцова
8995 25741 пирожковпая нет кафе город Москва, Новая Басманная улица, дом 20, с... 10 Новая Басманная улица
1729 59351 кафе «цветочный лес» нет кафе город Москва, Ломоносовский проспект, дом 29, ... 6 Ломоносовский проспект
8515 79707 ложки и вилки нет кафе город Москва, город Московский, Солнечная улиц... 36 Солнечная улица
12499 196550 суши сёри нет закусочная город Москва, поселение Десеновское, Нововатут... 0 Нововатутинский проспект
421 154627 tempo di pasta нет бар город Москва, Мясницкая улица, дом 24/7, строе... 90 Мясницкая улица
3280 29126 колледж железнодорожного и городского транспорта нет столовая город Москва, Каланчевская улица, дом 26, стро... 95 Каланчевская улица
1349 86309 ресторан «shelbybar» нет ресторан город Москва, Шелепихинская набережная, дом 20 75 Шелепихинская набережная
12012 177830 пицца паоло да предприятие быстрого обслуживания город Москва, Коломенская улица, дом 19, корпус 2 0 Коломенская улица
5802 140239 столовая нет столовая город Москва, Остаповский проезд, дом 3, строе... 30 Остаповский проезд
12706 194436 столовая гбоу школа № 1560 «лидер» нет столовая город Москва, улица Маршала Тухачевского, дом ... 250 улица Маршала Тухачевского
2921 19720 столовая нет столовая город Москва, проспект Вернадского, дом 82, ст... 328 проспект Вернадского
5428 20772 кафе обжорный ряд нет кафе город Москва, проспект Мира, дом 211, корпус 2 150 проспект Мира
In [39]:
data['street'].isnull().sum()
Out[39]:
243
In [40]:
data[data['street'].isnull()].sample(20)
Out[40]:
id object_name chain object_type address number street
1406 68113 френдс нет кафе город Москва, город Зеленоград, корпус 435 34 None
8549 127410 московский нет ресторан город Москва, город Московский, 1-й микрорайон... 70 None
12498 200258 кафе «старый кувшин» нет кафе город Москва, город Троицк, микрорайон "В", до... 50 None
9171 160284 столовая «cantina city» нет столовая город Москва, микрорайон Северное Чертаново, д... 88 None
4606 24503 квартал + нет ресторан город Москва, 2-й квартал Капотня, дом 22, кор... 60 None
6526 19739 кп мгу буфет 88 нет буфет город Москва, территория Ленинские Горы, дом 1 36 None
14817 219644 кафе нет закусочная город Москва, город Троицк, микрорайон "В", до... 0 None
6516 19727 кп мгу буфет 146 нет буфет город Москва, территория Ленинские Горы, дом 1 28 None
14058 205702 предприятие быстрого обслуживания «кофепит» нет предприятие быстрого обслуживания город Москва, микрорайон Северное Чертаново, к... 0 None
11782 185884 кафе нет кафе город Москва, поселение Марушкинское, вблизи д... 16 None
2413 138533 горница нет кафе город Москва, город Зеленоград, корпус 317А, с... 90 None
6533 23783 кп мгу столовая 1 нет столовая город Москва, территория Ленинские Горы, дом 1 232 None
10835 23837 школа 804 нет столовая город Москва, город Зеленоград, корпус 163 160 None
3443 141631 шаурум нет кафетерий город Москва, город Зеленоград, корпус 124, ст... 2 None
8726 124698 столовая в школе 2045 корп. 2312 нет столовая город Москва, город Зеленоград, корпус 2312 290 None
12458 193192 кулинария «брецель» нет кафетерий город Москва, город Зеленоград, корпус 1130 7 None
6532 23782 кп мгу столовая 2 нет столовая город Москва, территория Ленинские Горы, дом 1 230 None
11753 189124 шашлычный мир нет магазин (отдел кулинарии) город Москва, город Московский, 1-й микрорайон... 0 None
12457 198974 кафе брашна нет кафе город Москва, город Зеленоград, корпус 834В 45 None
11046 72084 столовая в школе 2045 корп.1611 (ранее увк 1762) нет столовая город Москва, город Зеленоград, корпус 1611 100 None

Вывод:

В таблице осталось 243 адреса, для которых значение улицы выделить не удалось. Это пригороды Москвы, например, Зеленоград, где идет наименование адреса с помощью 4-значного кода. Заведений там достаточно мало, поэтому оставим их со значением None.

Построим график топ-10 улиц по количеству объектов общественного питания.   

In [41]:
top_eat_street = data['street'].value_counts().head(10)
In [42]:
eat_street = data.groupby('street', as_index=False)['id'].count().sort_values('id', ascending=False).reset_index(drop=True)
In [43]:
eat_street
Out[43]:
street id
0 проспект Мира 204
1 Профсоюзная улица 183
2 Ленинградский проспект 173
3 Пресненская набережная 167
4 Варшавское шоссе 165
... ... ...
1958 улица Академика Комарова 1
1959 1-й Сетуньский проезд 1
1960 Денежный переулок 1
1961 улица Академика Опарина 1
1962 Пионерская улица 1

1963 rows × 2 columns

In [44]:
top_eat_street = eat_street[:10]
In [45]:
top_eat_street
Out[45]:
street id
0 проспект Мира 204
1 Профсоюзная улица 183
2 Ленинградский проспект 173
3 Пресненская набережная 167
4 Варшавское шоссе 165
5 Ленинский проспект 148
6 проспект Вернадского 132
7 Кутузовский проспект 114
8 Каширское шоссе 112
9 Кировоградская улица 110
In [46]:
fig = px.bar(top_eat_street, x='street', y='id', title='Топ-10 улиц с наибольшим количеством заведений')
fig.update_xaxes(tickangle=45)
fig.update_layout(legend_orientation="h",
                  xaxis_title='Название улицы',
                  yaxis_title='Количество заведений')
fig.show();
In [47]:
street_name = ['проспект Мира', 'Профсоюзная улица', 'Ленинградский проспект', 'Пресненская набережная', 'Варшавское шоссе', 
              'Ленинский проспект', 'проспект Вернадского', 'Кутузовский проспект', 'Каширское шоссе', 'Кировоградская улица']
street_km = [8.9, 9.3, 5.6, 0.55, 22.5, 14, 8, 8.3, 10.5, 4.23]
In [48]:
table = {'street':street_name, 'street_km':street_km}
In [49]:
long_streets = pd.DataFrame(table)
In [50]:
long_streets
Out[50]:
street street_km
0 проспект Мира 8.90
1 Профсоюзная улица 9.30
2 Ленинградский проспект 5.60
3 Пресненская набережная 0.55
4 Варшавское шоссе 22.50
5 Ленинский проспект 14.00
6 проспект Вернадского 8.00
7 Кутузовский проспект 8.30
8 Каширское шоссе 10.50
9 Кировоградская улица 4.23
In [51]:
top_eat_street = top_eat_street.merge(long_streets)
In [52]:
top_eat_street['rest_per_km'] = top_eat_street['id']/top_eat_street['street_km']
In [53]:
top_eat_street
Out[53]:
street id street_km rest_per_km
0 проспект Мира 204 8.90 22.921348
1 Профсоюзная улица 183 9.30 19.677419
2 Ленинградский проспект 173 5.60 30.892857
3 Пресненская набережная 167 0.55 303.636364
4 Варшавское шоссе 165 22.50 7.333333
5 Ленинский проспект 148 14.00 10.571429
6 проспект Вернадского 132 8.00 16.500000
7 Кутузовский проспект 114 8.30 13.734940
8 Каширское шоссе 112 10.50 10.666667
9 Кировоградская улица 110 4.23 26.004728
In [54]:
fig = px.bar(top_eat_street, x='street', y='rest_per_km', title='Концентрация заведений на популярных улицах')
fig.update_xaxes(tickangle=45)
fig.update_layout(legend_orientation="h",
                  xaxis_title='Название улицы',
                  yaxis_title='Количество ресторанов на 1 километр')
fig.show() 
In [55]:
def get_coords(address):
    BASE_URL = 'https://geocode-maps.yandex.ru/1.x/?apikey=bbe2afa2-bead-4eb2-807a-0e7ea42005ae&geocode=Москва,'+address
    try:
        req_text = requests.get(BASE_URL).text
        found_pos = re.findall('<pos>\d\d.\d* \d\d.\d*', req_text)
        position = found_pos[0]
        position = position[5:]
        return position
    except Exception:
        return None      
In [56]:
top_10_eat_street = list(top_eat_street['street'])
In [57]:
top_10_rest_street = data[data['street'].isin(top_10_eat_street)]
In [58]:
top_10_rest_street
Out[58]:
id object_name chain object_type address number street
151 155973 кафе «андерсон» да кафе город Москва, Варшавское шоссе, дом 2 150 Варшавское шоссе
152 23618 кафе «subway» да кафе город Москва, Варшавское шоссе, дом 7, корпус 1 36 Варшавское шоссе
153 155852 кафе «ламаджо» нет кафе город Москва, Варшавское шоссе, дом 29 30 Варшавское шоссе
154 152556 шаурма в пите нет предприятие быстрого обслуживания город Москва, Варшавское шоссе, дом 72, корпус 2 0 Варшавское шоссе
155 120658 выпечка нет кафетерий город Москва, Варшавское шоссе, дом 100 2 Варшавское шоссе
... ... ... ... ... ... ... ...
15308 213629 додо пицца да кафе город Москва, Пресненская набережная, дом 12 25 Пресненская набережная
15325 198436 милти да предприятие быстрого обслуживания город Москва, Ленинградский проспект, дом 80, ... 0 Ленинградский проспект
15347 222491 кальянная «мята lounge» да кафе город Москва, Профсоюзная улица, дом 142, корп... 40 Профсоюзная улица
15350 213061 мята да кафетерий город Москва, Каширское шоссе, дом 96, корпус 1 35 Каширское шоссе
15358 213724 шоколадница да кафе город Москва, Варшавское шоссе, дом 87Б 54 Варшавское шоссе

1508 rows × 7 columns

Чтобы не приходилось ждать каждый раз, когда отработает код (время ожидания от 2 минут до 6 минут), будем открывать предварительно сохраненные данные:

In [59]:
#CPU times: user 29.4 s, sys: 2.12 s, total: 31.5 s
#Wall time: 6min 46s

#top_10_rest_street['coords'] = top_10_rest_street['address'].apply(get_coords)  
In [60]:
#top_10_rest_street.to_csv('top_10_rest_street.csv', index=False)
In [61]:
#top_10_rest_street = pd.read_csv('top_10_rest_street.csv')
In [62]:
url = 'https://drive.google.com/file/d/12--anhtvZIEZeVAOraO5IKpQEwSW9OGa/view?usp=sharing'
path = 'https://drive.google.com/uc?export=download&id='+url.split('/')[-2]
top_10_rest_street = pd.read_csv(path)
In [63]:
top_10_rest_street
Out[63]:
id object_name chain object_type address number street coords
0 155973 кафе «андерсон» да кафе город Москва, Варшавское шоссе, дом 2 150 Варшавское шоссе 37.619683 55.699943
1 23618 кафе «subway» да кафе город Москва, Варшавское шоссе, дом 7, корпус 1 36 Варшавское шоссе 37.622405 55.700877
2 155852 кафе «ламаджо» нет кафе город Москва, Варшавское шоссе, дом 29 30 Варшавское шоссе 37.622432 55.693226
3 152556 шаурма в пите нет предприятие быстрого обслуживания город Москва, Варшавское шоссе, дом 72, корпус 2 0 Варшавское шоссе 37.618758 55.656869
4 120658 выпечка нет кафетерий город Москва, Варшавское шоссе, дом 100 2 Варшавское шоссе 37.618812 55.646228
... ... ... ... ... ... ... ... ...
1503 213629 додо пицца да кафе город Москва, Пресненская набережная, дом 12 25 Пресненская набережная 37.537083 55.749511
1504 198436 милти да предприятие быстрого обслуживания город Москва, Ленинградский проспект, дом 80, ... 0 Ленинградский проспект 37.511508 55.807951
1505 222491 кальянная «мята lounge» да кафе город Москва, Профсоюзная улица, дом 142, корп... 40 Профсоюзная улица 37.509334 55.625481
1506 213061 мята да кафетерий город Москва, Каширское шоссе, дом 96, корпус 1 35 Каширское шоссе 37.7123 55.614922
1507 213724 шоколадница да кафе город Москва, Варшавское шоссе, дом 87Б 54 Варшавское шоссе 37.620698 55.653644

1508 rows × 8 columns

In [64]:
top_10_rest_street[top_10_rest_street['coords'].isnull()] 
Out[64]:
id object_name chain object_type address number street coords
829 19715 комбинат питаная вагш нет столовая город Москва, проспект Вернадского, дом 100, к... 172 проспект Вернадского NaN

Для одного адреса из 1508 получить координаты автоматически не получилось, добавим их руками:

In [65]:
top_10_rest_street.loc[top_10_rest_street['object_name'] == 'комбинат питаная вагш', 'coords'] = top_10_rest_street\
    .loc[top_10_rest_street['object_name'] == 'комбинат питаная вагш', 'coords']\
    .astype(str).replace('None', '37.471524 55.649992', regex=True)

Получим районы Москвы на основе ранее вытянутых координат:

In [66]:
def get_district(coords):
    BASE_URL = 'https://geocode-maps.yandex.ru/1.x/?apikey=bbe2afa2-bead-4eb2-807a-0e7ea42005ae&geocode='+coords+'&kind=district&results=1'
    try:
        req_text = requests.get(BASE_URL).text
        soup = BeautifulSoup(req_text, 'lxml')
        found_district = soup.find_all('dependentlocalityname')  
        found_district = found_district[1]
        district = found_district.text
        return district
    except Exception:
        return None
In [67]:
#top_10_rest_street['district'] = top_10_rest_street['coords'].apply(get_district)     
In [68]:
#top_10_rest_street.to_csv('top_10_rest_street_with_districts.csv', index=False)
In [69]:
#top_10_rest_street_with_districts = pd.read_csv('top_10_rest_street_with_districts.csv')
In [70]:
url = 'https://drive.google.com/file/d/1jMGk_zyxCQdsV9s9AYTt0XmfqRhYcJWg/view?usp=sharing'
path = 'https://drive.google.com/uc?export=download&id='+url.split('/')[-2]
top_10_rest_street_with_districts = pd.read_csv(path)
In [71]:
top_10_rest_street_with_districts
Out[71]:
id object_name chain object_type address number street coords district
0 155973 кафе «андерсон» да кафе город Москва, Варшавское шоссе, дом 2 150 Варшавское шоссе 37.619683 55.699943 Донской район
1 23618 кафе «subway» да кафе город Москва, Варшавское шоссе, дом 7, корпус 1 36 Варшавское шоссе 37.622405 55.700877 Донской район
2 155852 кафе «ламаджо» нет кафе город Москва, Варшавское шоссе, дом 29 30 Варшавское шоссе 37.622432 55.693226 Донской район
3 152556 шаурма в пите нет предприятие быстрого обслуживания город Москва, Варшавское шоссе, дом 72, корпус 2 0 Варшавское шоссе 37.618758 55.656869 Нагорный район
4 120658 выпечка нет кафетерий город Москва, Варшавское шоссе, дом 100 2 Варшавское шоссе 37.618812 55.646228 Нагорный район
... ... ... ... ... ... ... ... ... ...
1503 213629 додо пицца да кафе город Москва, Пресненская набережная, дом 12 25 Пресненская набережная 37.537083 55.749511 Пресненский район
1504 198436 милти да предприятие быстрого обслуживания город Москва, Ленинградский проспект, дом 80, ... 0 Ленинградский проспект 37.511508 55.807951 район Сокол
1505 222491 кальянная «мята lounge» да кафе город Москва, Профсоюзная улица, дом 142, корп... 40 Профсоюзная улица 37.509334 55.625481 район Тёплый Стан
1506 213061 мята да кафетерий город Москва, Каширское шоссе, дом 96, корпус 1 35 Каширское шоссе 37.7123 55.614922 район Орехово-Борисово Северное
1507 213724 шоколадница да кафе город Москва, Варшавское шоссе, дом 87Б 54 Варшавское шоссе 37.620698 55.653644 Нагорный район

1508 rows × 9 columns

In [72]:
top_10_rest_district = top_10_rest_street_with_districts.groupby(['street', 'district'])['street'].nunique()
In [73]:
top_10_rest_district
Out[73]:
street                  district                       
Варшавское шоссе        Донской район                      1
                        Нагорный район                     1
                        район Нагатино-Садовники           1
                        район Чертаново Северное           1
                        район Чертаново Центральное        1
                        район Чертаново Южное              1
                        район Южное Бутово                 1
Каширское шоссе         район Москворечье-Сабурово         1
                        район Нагатино-Садовники           1
                        район Орехово-Борисово Северное    1
                        район Орехово-Борисово Южное       1
Кировоградская улица    район Чертаново Северное           1
                        район Чертаново Центральное        1
                        район Чертаново Южное              1
Кутузовский проспект    район Дорогомилово                 1
                        район Фили-Давыдково               1
Ленинградский проспект  Хорошёвский район                  1
                        район Аэропорт                     1
                        район Беговой                      1
                        район Сокол                        1
Ленинский проспект      Гагаринский район                  1
                        Донской район                      1
                        Ломоносовский район                1
                        Обручевский район                  1
                        район Проспект Вернадского         1
                        район Тропарёво-Никулино           1
                        район Тёплый Стан                  1
                        район Якиманка                     1
Пресненская набережная  Пресненский район                  1
Профсоюзная улица       Академический район                1
                        Обручевский район                  1
                        район Коньково                     1
                        район Тёплый Стан                  1
                        район Черёмушки                    1
                        район Ясенево                      1
проспект Вернадского    Гагаринский район                  1
                        Ломоносовский район                1
                        район Проспект Вернадского         1
                        район Раменки                      1
                        район Тропарёво-Никулино           1
проспект Мира           Алексеевский район                 1
                        Мещанский район                    1
                        Останкинский район                 1
                        Ярославский район                  1
                        район Ростокино                    1
                        район Свиблово                     1
Name: street, dtype: int64

Карта улиц с наибольшим количеством заведений общественного питания

Вывод:

Улицы, где расположено максимальное количество заведений, достаточно разные по длине и чаще всего проходят через несколько районов. Заметим, что улицы достаточно близки к центру и уходят на юг города.

Найдем число улиц с одним объектом общественного питания.   

In [74]:
loosers_street = eat_street.query('id == 1')
In [75]:
loosers_street
Out[75]:
street id
1379 2-я Сокольническая улица 1
1380 улица Кубинка 1
1381 Песчаная улица 1
1382 улица Кухмистерова 1
1383 3-я Северная линия 1
... ... ...
1958 улица Академика Комарова 1
1959 1-й Сетуньский проезд 1
1960 Денежный переулок 1
1961 улица Академика Опарина 1
1962 Пионерская улица 1

584 rows × 2 columns

In [76]:
#CPU times: user 11.2 s, sys: 854 ms, total: 12.1 s
#Wall time: 1min 48s
#import warnings
#warnings.filterwarnings("ignore")

#loosers_street['coords'] = loosers_street['street'].apply(get_coords) 
In [77]:
#loosers_street.to_csv('loosers_street_with_coords.csv', index=False)
In [78]:
#loosers_street = pd.read_csv('loosers_street_with_coords.csv')
In [79]:
url = 'https://drive.google.com/file/d/1jc-fp1wpFj9P3ghcHiBX5U_4w3lR2gDf/view?usp=sharing'
path = 'https://drive.google.com/uc?export=download&id='+url.split('/')[-2]
loosers_street = pd.read_csv(path)
In [80]:
loosers_street
Out[80]:
street id coords
0 2-я Сокольническая улица 1 37.682467 55.786748
1 улица Кубинка 1 37.407304 55.721062
2 Песчаная улица 1 37.512434 55.801845
3 улица Кухмистерова 1 37.724086 55.685132
4 3-я Северная линия 1 37.552534 55.942368
... ... ... ...
579 улица Академика Комарова 1 37.593354 55.830007
580 1-й Сетуньский проезд 1 37.541988 55.731293
581 Денежный переулок 1 37.586769 55.744971
582 улица Академика Опарина 1 37.503666 55.646035
583 Пионерская улица 1 37.634335 55.727247

584 rows × 3 columns

In [81]:
#CPU times: user 12.9 s, sys: 838 ms, total: 13.8 s
#Wall time: 2min 37s

#import warnings
#warnings.filterwarnings("ignore")

#loosers_street['district'] = loosers_street['coords'].apply(get_district)     
In [82]:
#loosers_street.to_csv('loosers_street_with_district.csv', index=False)
In [83]:
#loosers_street_with_district = pd.read_csv('loosers_street_with_district.csv')
In [84]:
url = 'https://drive.google.com/file/d/1WtY6I83nGUUKKuRkeloF4bDP9FEo05Wp/view?usp=sharing'
path = 'https://drive.google.com/uc?export=download&id='+url.split('/')[-2]
loosers_street_with_district = pd.read_csv(path)
In [85]:
loosers_street_with_district
Out[85]:
street id coords district
0 2-я Сокольническая улица 1 37.682467 55.786748 район Сокольники
1 улица Кубинка 1 37.407304 55.721062 Можайский район
2 Песчаная улица 1 37.512434 55.801845 район Сокол
3 улица Кухмистерова 1 37.724086 55.685132 район Печатники
4 3-я Северная линия 1 37.552534 55.942368 район Северный
... ... ... ... ...
579 улица Академика Комарова 1 37.593354 55.830007 район Марфино
580 1-й Сетуньский проезд 1 37.541988 55.731293 район Раменки
581 Денежный переулок 1 37.586769 55.744971 район Хамовники
582 улица Академика Опарина 1 37.503666 55.646035 район Коньково
583 Пионерская улица 1 37.634335 55.727247 район Замоскворечье

584 rows × 4 columns

In [86]:
loosers_district = loosers_street_with_district['district'].value_counts().head(10)
In [87]:
loosers_district
Out[87]:
Таганский район        28
район Хамовники        23
Басманный район        23
Пресненский район      20
Тверской район         20
Тимирязевский район    19
район Марьина Роща     17
район Сокольники       15
район Замоскворечье    15
Мещанский район        14
Name: district, dtype: int64

Вывод:

В центральных районах Москвы достаточно много улиц, на которых находится всего 1 заведение общественного питания. Всего в Москве 584 улицы с 1 заведением.

Посмотрим на распределение количества посадочных мест для улиц с большим количеством объектов общественного питания.   

In [88]:
top_10_rest_street.describe()
Out[88]:
id number
count 1508.000000 1508.000000
mean 126665.931034 57.965517
std 72453.593626 89.955523
min 19654.000000 0.000000
25% 29385.500000 12.000000
50% 150752.500000 38.500000
75% 188530.500000 75.000000
max 223439.000000 1700.000000
In [89]:
plt.figure(figsize=(16, 8))
plt.title('Распределение количества посадочных мест для улиц с большим количеством объектов общественного питания')
ax = sns.boxplot(x='number', y='street', data=top_10_rest_street)
plt.xlabel('Количество посадочных мест')
plt.ylabel('Название улицы')
plt.show()
In [90]:
top_10_rest_street = top_10_rest_street.groupby('street')['number'].sum().reset_index()
In [91]:
top_10_rest_street = top_10_rest_street.merge(long_streets)
In [92]:
top_10_rest_street['numbers_per_km'] = top_10_rest_street['number']/top_10_rest_street['street_km']
In [93]:
top_10_rest_street
Out[93]:
street number street_km numbers_per_km
0 Варшавское шоссе 8626 22.50 383.377778
1 Каширское шоссе 6171 10.50 587.714286
2 Кировоградская улица 6577 4.23 1554.846336
3 Кутузовский проспект 9697 8.30 1168.313253
4 Ленинградский проспект 9042 5.60 1614.642857
5 Ленинский проспект 9346 14.00 667.571429
6 Пресненская набережная 7656 0.55 13920.000000
7 Профсоюзная улица 8667 9.30 931.935484
8 проспект Вернадского 8840 8.00 1105.000000
9 проспект Мира 12790 8.90 1437.078652
In [94]:
fig = px.bar(top_10_rest_street, x='street', y='numbers_per_km', title='Концентрация посадочных мест на популярных улицах')
fig.update_xaxes(tickangle=45)
fig.update_layout(legend_orientation="h",
                  xaxis_title='Название улицы',
                  yaxis_title='Количество посадочных мест на 1 километр')
fig.show() 

Вывод:

Максимальное количество посадочных мест находится на проспекте Мира, но важно помнить, что улица длинная. Если рассчитать показатель «Количество посадочных мест на 1 километр», то вперёд вырывается Пресненская набережная, на 550 метрах находится 7656 посадочных мест в заведении.

Шаг 3. Общий вывод

Вывод:

Результаты исследования:

  • почти 40% рынка — это кафе;

  • 80% заведений — это не сетевые объекты, количество посадочных мест у них значительно больше, чем в сетевых заведениях;

  • чаще всего сетевыми становятся предприятия быстрого обслуживания — 41% сетевых заведений. Из кафе к сетевым относятся 22.9% заведений;

  • больше всего посадочных мест бывает в столовых, а в кафе средняя цифра — 40 мест;

  • улицы, где расположено максимальное количество заведений, достаточно разные по длине и проходят через несколько районов. Пресненская набережная — исключение, она короткая и там максимальная концентрация заведений;

  • в Москве больше 20 районов, где находится всего 1 заведение общественного питания, и 584 улицы, на которых 1 заведение.

Рекомендации:

Кафе, для которого проводилось исследование, оригинальное и дорогое, поэтому думать про сетевой формат сложно и рано. В среднем в кафе около 40 посадочных мест, но если оно уникальное, можно сделать меньше посадочных мест, а ажиотаж создать атмосферой. Для принятия решения о выборе района или улицы нужно больше данных, например, стоимость аренды, платежеспособность жителей этого района и их количество. На первый взгляд, хорошим вариантом будет расположить кафе в Сити, чтобы это находило отклик в атмосфере заведения. Однако на Пресненской набережной сейчас максимальная концентрация заведений. Вероятно, можно рассмотреть места с видом на Сити (кафе на Эйфелевой башне менее привлекательно, чем кафе с видом на неё).

Презентация:

In [ ]: